package com.sc.nft.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.DaoEcologyPointsWalletDao;
import com.sc.nft.dao.DaoEcologyPointsWalletLogDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.AdminDaoEcologyPointsWalletLogPageVO;
import com.sc.nft.entity.vo.AdminDaoEcologyPointsWalletVO;
import com.sc.nft.enums.DaoEcologyPointsWalletLogTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.DaoEcologyPointsWalletLogService;
import com.sc.nft.service.DaoEcologyPointsWalletService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * Dao生态积分钱包 服务实现类
 * </p>
 *
 * @author liGen
 * @since 2024-11-26
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DaoEcologyPointsWalletServiceImpl implements DaoEcologyPointsWalletService {


    private final DaoEcologyPointsWalletDao daoEcologyPointsWalletDao;

    private final DaoEcologyPointsWalletLogDao daoEcologyPointsWalletLogDao;
    private final DaoEcologyPointsWalletLogService daoEcologyPointsWalletLogService;


//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void editDaoPoints(Long daoId, Boolean isAdd, String amount, String remark) {
//        DaoEcologyPointsWallet daoEcologyPointsWallet = daoEcologyPointsWalletDao.getByDaoId(daoId);
//        Assert.notNull(daoEcologyPointsWallet, () -> new GlobalRunTimeException("dao不存在"));
//
//        if (isAdd) {
//            addAmount(daoId, Convert.toBigDecimal(amount), DaoEcologyPointsWalletLogTypeEnum.SYSTEM_PROCESSING, remark);
//        } else {
//            subAllAmount(daoId, Convert.toBigDecimal(amount), DaoEcologyPointsWalletLogTypeEnum.SYSTEM_PROCESSING, remark);
//        }
//    }
//
//
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void addAmount(Long daoId, BigDecimal amount, DaoEcologyPointsWalletLogTypeEnum type, String remark) {
//        DaoEcologyPointsWallet daoEcologyPointsWallet = daoEcologyPointsWalletDao.getByDaoId(daoId);
//        Assert.isTrue(daoEcologyPointsWalletDao.addAmount(daoId, amount), () -> new GlobalRunTimeException("增加待释放金额失败"));
//
//        DaoEcologyPointsWalletLog pointsWalletLog = new DaoEcologyPointsWalletLog();
//        pointsWalletLog.setDaoId(daoId);
//        pointsWalletLog.setType(type);
//        pointsWalletLog.setTypeName(type.getDescription());
//        pointsWalletLog.setAmount(amount);
//        pointsWalletLog.setBeforeBalance(daoEcologyPointsWallet.getAmount());
//        pointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().add(amount));
//        pointsWalletLog.setIsAdd(Boolean.TRUE);
//        pointsWalletLog.setRemark(remark);
//        pointsWalletLog.insert();
//
//        if (type == DaoEcologyPointsWalletLogTypeEnum.SYSTEM_PROCESSING) {
//
//            AdminDaoEcologyPointsWalletLog adminDaoEcologyPointsWalletLog = new AdminDaoEcologyPointsWalletLog();
//            adminDaoEcologyPointsWalletLog.setDaoId(daoId);
//            adminDaoEcologyPointsWalletLog.setAmount(amount);
//            adminDaoEcologyPointsWalletLog.setBeforeBalance(daoEcologyPointsWallet.getAmount());
//            adminDaoEcologyPointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().add(amount));
//            adminDaoEcologyPointsWalletLog.setIsAdd(Boolean.TRUE);
//            adminDaoEcologyPointsWalletLog.setRemark(remark);
//            adminDaoEcologyPointsWalletLog.insert();
//        }
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void subAllAmount(Long daoId, BigDecimal amount, DaoEcologyPointsWalletLogTypeEnum type, String remark) {
//        DaoEcologyPointsWallet daoEcologyPointsWallet = daoEcologyPointsWalletDao.getByDaoId(daoId);
//        Assert.isTrue(daoEcologyPointsWalletDao.subAllAmount(daoId, amount), () -> new GlobalRunTimeException("增加待释放金额失败"));
//
//        DaoEcologyPointsWalletLog pointsWalletLog = new DaoEcologyPointsWalletLog();
//        pointsWalletLog.setDaoId(daoId);
//        pointsWalletLog.setType(type);
//        pointsWalletLog.setTypeName(type.getDescription());
//        pointsWalletLog.setAmount(amount);
//        pointsWalletLog.setBeforeBalance(daoEcologyPointsWallet.getAmount());
//        pointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().subtract(amount));
//        pointsWalletLog.setIsAdd(Boolean.FALSE);
//        pointsWalletLog.setRemark(StrUtil.EMPTY);
//        pointsWalletLog.insert();
//
//        if (type == DaoEcologyPointsWalletLogTypeEnum.SYSTEM_PROCESSING) {
//            AdminDaoEcologyPointsWalletLog adminDaoEcologyPointsWalletLog = new AdminDaoEcologyPointsWalletLog();
//            adminDaoEcologyPointsWalletLog.setDaoId(daoId);
//            adminDaoEcologyPointsWalletLog.setAmount(amount);
//            adminDaoEcologyPointsWalletLog.setBeforeBalance(daoEcologyPointsWallet.getAmount());
//            adminDaoEcologyPointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().subtract(amount));
//            adminDaoEcologyPointsWalletLog.setIsAdd(Boolean.FALSE);
//            adminDaoEcologyPointsWalletLog.setRemark(remark);
//            adminDaoEcologyPointsWalletLog.insert();
//        }
//    }

    @Override
    public Page<AdminDaoEcologyPointsWalletVO> getPage(String daoName, Integer pageNo, Integer pageSize) {
        return daoEcologyPointsWalletDao.getPage(daoName, new Page<>(pageNo, pageSize));
    }

    @Override
    public Page<AdminDaoEcologyPointsWalletLogPageVO> adminDaoEcologyPointsWalletLogPage(Long daoId,Long walletId, DaoEcologyPointsWalletLogTypeEnum type, Date startTime, Date endTime, Integer pageNo, Integer pageSize) {
        return daoEcologyPointsWalletLogDao.adminDaoEcologyPointsWalletLogPage(new Page<>(pageNo, pageSize), daoId,walletId, ObjectUtil.isNull(type) ? null : type.getCode(), startTime, endTime);

    }


    @Override
    public DaoEcologyPointsWallet getByDaoIdAndPointsId(Long daoId, Long pointsId) {
        return daoEcologyPointsWalletDao.getByDaoIdAndPointsId(daoId, pointsId);
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editDaoPoints(Long daoId, Long pointId, String pointName, BigDecimal sumCount, DaoEcologyPointsWalletLogTypeEnum daoEcologyPointsWalletLogTypeEnum, String remark) {
        //要加的金额
        BigDecimal amount = Convert.toBigDecimal(sumCount).setScale(2,BigDecimal.ROUND_DOWN);
        Assert.isTrue(NumberUtil.isGreater(amount,BigDecimal.ZERO),()-> new GlobalRunTimeException("金额不能小于0"));
        Assert.isTrue(adjustAmount(daoId,pointId,pointName,amount,
                daoEcologyPointsWalletLogTypeEnum,remark),()-> new GlobalRunTimeException("操作失败"));

    }
    @Override
    public boolean adjustAmount(Long daoId, Long pointId, String pointName, BigDecimal sumCount, DaoEcologyPointsWalletLogTypeEnum daoEcologyPointsWalletLogTypeEnum, String remark) {
        DaoEcologyPointsWallet daoEcologyPointsWallet = daoEcologyPointsWalletDao.getByDaoIdAndPointsId(daoId, pointId);
        if (Objects.isNull(daoEcologyPointsWallet)) {
            daoEcologyPointsWallet = saveWallet(daoId, pointId, pointName, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
            if (!daoEcologyPointsWalletLogTypeEnum.getIsAdd()) {
                return Boolean.FALSE;
            }
        }
        Boolean walletFlag = Boolean.FALSE;
        Boolean walletLogFlag = Boolean.FALSE;
        if (daoEcologyPointsWalletLogTypeEnum.getIsAdd()) {
            // 添加
            walletFlag = daoEcologyPointsWalletDao.addAmount(daoEcologyPointsWallet.getId(), sumCount, daoEcologyPointsWallet.getAmount());
        } else {
            // 减少
            if (daoEcologyPointsWallet.getAmount().compareTo(sumCount) < 0) {
                return Boolean.FALSE;
            }
            walletFlag = daoEcologyPointsWalletDao.subAmount(daoEcologyPointsWallet.getId(), sumCount, daoEcologyPointsWallet.getAmount());
        }
        DaoEcologyPointsWalletLog daoEcologyPointsWalletLog = new DaoEcologyPointsWalletLog();
        daoEcologyPointsWalletLog.setDaoId(daoId);
        daoEcologyPointsWalletLog.setUserEcologyPointsWalletId(daoEcologyPointsWallet.getId());
        daoEcologyPointsWalletLog.setType(daoEcologyPointsWalletLogTypeEnum);
        daoEcologyPointsWalletLog.setTypeName(daoEcologyPointsWalletLogTypeEnum.getDescription());
        daoEcologyPointsWalletLog.setAmount(sumCount);
        daoEcologyPointsWalletLog.setBeforeBalance(daoEcologyPointsWallet.getAmount());
        if (daoEcologyPointsWalletLogTypeEnum.getIsAdd()) {
            daoEcologyPointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().add(sumCount));
        } else {
            daoEcologyPointsWalletLog.setAfterBalance(daoEcologyPointsWallet.getAmount().subtract(sumCount));
        }
        daoEcologyPointsWalletLog.setIsAdd(daoEcologyPointsWalletLogTypeEnum.getIsAdd());
        daoEcologyPointsWalletLog.setRemark(remark);
        walletLogFlag = daoEcologyPointsWalletLogService.save(daoEcologyPointsWalletLog);


        return walletFlag && walletLogFlag;
    }

    private DaoEcologyPointsWallet saveWallet(Long daoId, Long pointId, String pointName, BigDecimal amount, BigDecimal sumExpendAmount, BigDecimal sumIncomeAmount) {
        DaoEcologyPointsWallet daoEcologyPointsWallet = new DaoEcologyPointsWallet();
        daoEcologyPointsWallet.setDaoId(daoId);
        daoEcologyPointsWallet.setPointsId(pointId);
        daoEcologyPointsWallet.setPointsName(pointName);
        daoEcologyPointsWallet.setAmount(amount);
        daoEcologyPointsWallet.setSumExpendAmount(sumExpendAmount);
        daoEcologyPointsWallet.setSumIncomeAmount(sumIncomeAmount);
        daoEcologyPointsWalletDao.save(daoEcologyPointsWallet);
        return daoEcologyPointsWallet;
    }
}
